package com.settlement.system.service.impl;

import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.common.util.SecurityUtils;
import com.settlement.system.common.util.common.CommonAcsUtil;
import com.settlement.system.common.util.common.SystemUserUtil;
import com.settlement.system.mapper.BaseMapper;
import com.settlement.system.mapper.TblAcsRoleBillStatusMapper;
import com.settlement.system.mapper.TblRefundAuditBillDtlMapper;
import com.settlement.system.mapper.TblRefundAuditBillMapper;
import com.settlement.system.mapper.security.userdetails.SysUserDetails;
import com.settlement.system.model.entity.common.*;
import com.settlement.system.service.ITblAcsUserRoleAuthorityService;
import com.settlement.system.service.ITblRefundAuditBillDtlService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 退款稽核单据明细表 服务实现类
 *
 * @author xiaochuan
 * @since 2020-06-24
 */
@Service
@Slf4j
public class TblRefundAuditBillDtlServiceImpl extends BaseServiceImpl implements ITblRefundAuditBillDtlService {

    @Resource
    private TblRefundAuditBillDtlMapper tblRefundAuditBillDtlMapper;

    @Resource
    private TblRefundAuditBillMapper tblRefundAuditBillMapper;

    @Resource
    private TblAcsRoleBillStatusMapper tblAcsRoleBillStatusMapper;

    @Resource
    private ITblAcsUserRoleAuthorityService tblAcsUserRoleAuthorityService;

    @Override
    public BaseMapper init() {
        return tblRefundAuditBillDtlMapper;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = ServiceException.class)
    public void insertDtl(TblRefundAuditBill bill, TblRefundAuditBillDtl currentDtl, TblRefundAuditBillDtl lastDtl) throws ServiceException {
        try {
            //插入操作日志
            tblRefundAuditBillDtlMapper.insert(currentDtl);
            //更新主表信息
            tblRefundAuditBillMapper.updateByBillNo(bill);

            //更新最后一条日志单据状态
            //tblRefundAuditBillDtlMapper.update(lastDtl);

            final String keptOnFile = "归档";
            //如果单据归档，需要更新缓存表结束方式
            if (StringUtils.equals(keptOnFile, currentDtl.getBillStatusName())) {
                tblRefundAuditBillMapper.updateRefundAuditCache(3, currentDtl.getBillNo());
            }
        } catch (Exception e) {
            throw new ServiceException("新增数据异常,数据已经回滚", e);
        }
    }

    /**
     * 更新主表和明细表数据，分情况进行处理
     *
     * @param user   用户信息
     * @param billNo 退款稽核单据
     * @throws ServiceException
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = ServiceException.class)
    public void updateBillStatus(SysUserDetails user, String billNo) throws ServiceException {
        try {
            Map<String, Object> params = new HashMap<>(16);
            params.put("billNo", billNo);
            List<TblRefundAuditBillDtl> allList = tblRefundAuditBillDtlMapper.selectByParam(params);
            List<TblRefundAuditBill> mainList = tblRefundAuditBillMapper.selectByParam(params);
            TblRefundAuditBill bill = new TblRefundAuditBill();
           /* 最后一条有效的数据
            TblRefundAuditBillDtl currenDtl = lastEfficetList.get(0);
           currenDtl.setUpdateUser(user.getUsername());
           currenDtl.setUpdateTime(new Date());
           currenDtl.setCreateUser(user.getUsername());
           currenDtl.setCreateTime(new Date());
           currenDtl.setId(CommonAcsUtil.generateUUId());
           currenDtl.setStatusName("确认");
           currenDtl.setOrderField(allList.get(0).getOrderField() + 1);*/

            params.put("id", mainList.get(0).getDealDtlId());
            List<TblRefundAuditBillDtl> dealDtlList = tblRefundAuditBillDtlMapper.selectByParam(params);

            params.put("id", dealDtlList.get(0).getLastEffectiveId());
            List<TblRefundAuditBillDtl> lastEfficetList = tblRefundAuditBillDtlMapper.selectByParam(params);
            PropertyUtils.copyProperties(bill, lastEfficetList.get(0));

            TblRefundAuditBillDtl currenDtl = dealDtlList.get(0);
            currenDtl.setUpdateUser(user.getUsername());
            currenDtl.setUpdateTime(new Date());
            currenDtl.setCreateUser(user.getUsername());
            currenDtl.setCreateTime(new Date());
            currenDtl.setId(CommonAcsUtil.generateUUId());
            currenDtl.setStatusName("撤销");
            currenDtl.setOrderField(allList.get(0).getOrderField() + 1);

            bill.setUpdateUser(user.getUsername());
            bill.setUpdateTime(new Date());
            bill.setDealDtlId(lastEfficetList.get(0).getId());

            //TblRefundAuditBillDtl lastDtl = new TblRefundAuditBillDtl();
            //lastDtl.setId(mainList.get(0).getDealDtlId());
            //lastDtl.setStatusName("撤销");

            //更新主表信息
            tblRefundAuditBillMapper.updateByBillNo(bill);
            //更新最后一条数据为撤销
            //tblRefundAuditBillDtlMapper.update(lastDtl);
            //新增待处理明细
            tblRefundAuditBillDtlMapper.insert(currenDtl);

        } catch (Exception e) {
            throw new ServiceException("撤销数据异常", e);
        }
    }

    @Override
    public List<TblRefundAuditBillDtl> selectLastEffective(Map<String, Object> params) throws ServiceException {
        try {
            return tblRefundAuditBillDtlMapper.selectLastEffective(params);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List<TblRefundAuditBillDtl> selectLastSecond(Map<String, Object> params) throws ServiceException {
        try {
            return tblRefundAuditBillDtlMapper.selectLastSecond(params);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public List<TblRefundAuditBillDtl> selectRoleStatus(Map<String, Object> params) throws ServiceException {
        try {
            return tblRefundAuditBillDtlMapper.selectRoleStatus(params);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public Map<String, Object> batchSaveRefundCheckDtl(TblRefundAuditBillDtl tblRefundAuditBillDtl) throws ServiceException {
        Map<String, Object> resultMap = new HashMap<String, Object>(16);
        ArrayList<String> billNoList = new ArrayList<String>();
        final char charEnglishComma = ',';
        if (StringUtils.indexOf(tblRefundAuditBillDtl.getBillNo(), charEnglishComma) != -1) {
            String[] billNoArr = tblRefundAuditBillDtl.getBillNo().split(",");
            for (String billNo : billNoArr) {
                billNoList.add(billNo);
            }
        } else {
            billNoList.add(tblRefundAuditBillDtl.getBillNo());
        }
        ArrayList<String> succList = new ArrayList<String>();
        ArrayList<String> failList = new ArrayList<String>();
        boolean resultFlag = false;
        if (billNoList != null && billNoList.size() > 0) {
            for (String billNo : billNoList) {
                tblRefundAuditBillDtl.setBillNo(billNo);
                resultFlag = saveRefundCheckDtl(tblRefundAuditBillDtl);
                if (resultFlag) {
                    succList.add(billNo);
                } else {
                    failList.add(billNo);
                }
            }
        }
        log.info("批量处理退款稽核，处理完成，返回结果succNum={},succList={},failNum={},failList={}", succList.size(), succList, failList.size(), failList);
        resultMap.put("succNum", succList.size());
        resultMap.put("failNum", failList.size());
        return resultMap;
    }

    private boolean saveRefundCheckDtl(TblRefundAuditBillDtl tblRefundAuditBillDtl) {
        String billNo = tblRefundAuditBillDtl.getBillNo();
        if (StringUtils.isEmpty(billNo)) {
            log.error("批量处理退款稽核，单据编码不能为空，请核实");
            return false;
        }
        try {
            Map<String, Object> paramMap = new HashMap<>(16);
            paramMap.put("billNo", billNo);
            List<TblRefundAuditBillDtl> billList = selectRoleStatus(paramMap);
            if (CollectionUtils.isEmpty(billList)) {
                log.error("批量处理退款稽核，单据编码{}已经被归档，不允许在进行操作，请核实", billNo);
                return false;
            }
            SysUserDetails user = SecurityUtils.getUser();;
            //判断下最新一条记录是不是进行撤销用户所属角色，并且用户具有写的权限
            Map<String, Object> paramsUser = new HashMap<>(16);
            paramsUser.put("roleNo", billList.get(0).getRoleNo());
            paramsUser.put("authorityNo", "auth_002");
            paramsUser.put("loginName", user.getUsername());
            List<TblAcsUserRoleAuthority> auth = tblAcsUserRoleAuthorityService.selctAllUserInfo(paramsUser);
            if (CollectionUtils.isEmpty(auth)) {
                log.error("批量处理退款稽核，单据编码{}的状态已经与你不匹配，请确认当前单据是否已经被处理！", billNo);
                return false;
            }
            //校验完成，开始处理
            TblRefundAuditBill tblRefundAuditBill = new TblRefundAuditBill();
            Map<String, Object> billParams = new HashMap<>(16);
            billParams.put("billNo", tblRefundAuditBillDtl.getBillNo());
            List<TblRefundAuditBill> refundAuditBillList = tblRefundAuditBillMapper.selectByParam(billParams);
            if (!CollectionUtils.isEmpty(refundAuditBillList)) {
                if (StringUtils.isEmpty(refundAuditBillList.get(0).getFirstServicePerson())) {
                    tblRefundAuditBill.setFirstServicePersonName(user.getUsername());
                    tblRefundAuditBill.setFirstServicePerson(user.getUsername());
                }
            }
            tblRefundAuditBillDtl.setResponsiblePerson(user.getUsername());
            //属性赋值
            PropertyUtils.copyProperties(tblRefundAuditBill, tblRefundAuditBillDtl);
            //单据明细
            tblRefundAuditBillDtl.setId(CommonAcsUtil.generateUUId());
            tblRefundAuditBillDtl.setCreateTime(new Date());
            tblRefundAuditBillDtl.setCreateUser(user.getUsername());
            tblRefundAuditBillDtl.setUserName(user.getUsername());
            tblRefundAuditBillDtl.setLoginName(user.getUsername());
            //单据主表
            tblRefundAuditBill.setDealDtlId(tblRefundAuditBillDtl.getId());
            tblRefundAuditBill.setUpdateTime(new Date());
            tblRefundAuditBill.setUpdateUser(user.getUsername());

            billParams.put("billStatusNo", tblRefundAuditBillDtl.getBillStatusNo());
            List<TblAcsRoleBillStatus> acsRoleBillStatusList = tblAcsRoleBillStatusMapper.selectByParam(billParams);
            tblRefundAuditBillDtl.setRoleNo(acsRoleBillStatusList.get(0).getRoleNo());
            tblRefundAuditBillDtl.setStatusName("确认");
            tblRefundAuditBillDtl.setUpdateTime(new Date());
            tblRefundAuditBillDtl.setUpdateUser(user.getUsername());

            List<TblRefundAuditBillDtl> refundAuditBillDtlList = tblRefundAuditBillDtlMapper.selectByParam(billParams);
            tblRefundAuditBillDtl.setOrderField(refundAuditBillDtlList.get(0).getOrderField() + 1);
            tblRefundAuditBillDtl.setLastEffectiveId(refundAuditBillList.get(0).getDealDtlId());

            TblRefundAuditBillDtl oldTblRefundAuditBillDtl = new TblRefundAuditBillDtl();
            //保存操作
            insertDtl(tblRefundAuditBill, tblRefundAuditBillDtl, oldTblRefundAuditBillDtl);
            log.error("批量处理退款稽核单据成功===true，单据编码billNo={}", billNo);
            return true;
        } catch (Exception e) {
            log.error("批量处理退款稽核异常，单据编码为{}", billNo);
            return false;
        }
    }
}

